/*================================================================
*   Copyright (C) 2021 Sangfor Ltd. All rights reserved.
*   
*   文件名称：cond.c
*   创 建 者：wudu
*   创建日期：2021年07月06日
*   描    述：
*
================================================================*/

#include <stdio.h>
#include <unistd.h>
#include <pthread.h>

#define THREADCOUNT 2

int g_bowl = 0;
pthread_mutex_t g_lock;


//测试只有一个条件变量的时候
//eat cond
pthread_cond_t g_cond;
//make cond
pthread_cond_t g_makecond;

void* EatThreadStart(void* arg)
{
    (void)arg;
    while(1)
    {
        pthread_mutex_lock(&g_lock);
        //测试while判断条件
        //while在这里非常重要
        while(g_bowl <= 0)
        {
            pthread_cond_wait(&g_cond, &g_lock);
        }
        printf("i am %p, i eat %d\n", pthread_self(), --g_bowl);
        pthread_mutex_unlock(&g_lock);
        pthread_cond_signal(&g_makecond);
    }
    return NULL;
}

void* MakeThreadStart(void* arg)
{
    (void)arg;
    while(1)
    {
        pthread_mutex_lock(&g_lock);
        while(g_bowl > 0)
        {
            pthread_cond_wait(&g_makecond, &g_lock);
        }
        printf("i am %p, i make %d\n", pthread_self(), ++g_bowl);
        pthread_mutex_unlock(&g_lock);
        pthread_cond_signal(&g_cond);
    }
    return NULL;
}


int main()
{
    /*
     * 创建吃面和创建做面的人
     * */

    pthread_mutex_init(&g_lock, NULL);
    pthread_cond_init(&g_cond, NULL);
    pthread_cond_init(&g_makecond, NULL);

    pthread_t EatThread[THREADCOUNT], MakeThread[THREADCOUNT];
    for(int i = 0; i < THREADCOUNT; i++)
    {
        int ret =pthread_create(&EatThread[i], NULL, EatThreadStart, NULL);
        if(ret < 0)
        {
            perror("pthread_create");
            return 0;
        }
        ret =pthread_create(&MakeThread[i], NULL, MakeThreadStart, NULL);
        if(ret < 0)
        {
            perror("pthread_create");
            return 0;
        }
    }
    

    for(int i = 0; i < THREADCOUNT; i++)
    {
        pthread_join(EatThread[i], NULL);
        pthread_join(MakeThread[i], NULL);
    }

    pthread_mutex_destroy(&g_lock);
    pthread_cond_destroy(&g_cond);
    pthread_cond_destroy(&g_makecond);
    return 0;
}
